import java.io.*;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Stack;
import java.util.Random;
import java.lang.Math;
import java.lang.String;

class HandCompTest{
	
	public HandCompTest(){
		
	}
	public int handComp(Card[] passedIn) {
		
		
		int rating = 0;
		// 0 - 209 high card
		// 210 - 419 one pair
		// 420 - 629 two pair 
		// 630 - 839 three of a kind
		// 840 - 1049 straight
		// 1050 - 1259 flush
		// 1260 - 1469 full house
		// 1470 - 1679 four of a kind
		// 1680 - 1889 straight flush
		// 2099 royal flush
		
		char flushSuit = 'z';
		int fourOfAKind = 0;
		int threeOfAKindA = 0;
		int threeOfAKindTemp = 0;
		int twoOfAKindA = 0;
		int twoOfAKindB = 0;
		int twoOfAKindTemp = 0;
		int swapKind = 0;
		int highCard = 0;
		int j=0;
		
		int cardPtr = 0;
		int straightCount = 1;	
		int initialCardValue;
		
		BigHand hand = new BigHand();
		
		int count = 0;
		for(int z = 0; z < passedIn.length; z++){
			hand.receiveCard(passedIn[z]);
			count++;
		}	
		Card filler = new Card( -2, 'x');
		while(count < 7){
			hand.receiveCard(filler);
			count++;
		}
		
		BigHand smallerHand = new BigHand();
		BigHand smallerHandB = new BigHand();
		
		/////////////////////////////////////////////////////////////////////////////////////
		// add -1 , f's to end ot make it 7 every time
		/////////////////////////////////////////////////////////////////////////////////////
		
		// bubble sort putting aces in frotn and decending from left to right
		int x;
		int temp;
		int temp2;
		Card tCard;
		boolean swaps = true;
		count = 0;
		while (swaps && count < 8){
			swaps = false;
			for(x = 0; x < 6; x++){
				// if has extra condition to make sure Aces are at the end
				temp = hand.viewCard(x).getNumber();
				temp2 = hand.viewCard(x+1).getNumber();
				if(temp == 1)
					temp = 14;
				if(temp2 == 1)
					temp2 = 14;
				// do bubbling	
				if(temp < temp2){
					// swap elements
					swaps = true;
					tCard = hand.viewCard(x);
					hand.setCard(x, hand.viewCard(x+1));
					hand.setCard(x+1, tCard);
				}
			}
			count++;
		}

		
		int suits[] = new int[4];	// will hold hte amount of time each suit is used
		suits[0] = 0;	// spades
		suits[1] = 0;	// diamonds
		suits[2] = 0;	// hearts
		suits[3] = 0;	// clubs
		for(j = 0; j < 7; j++){
			// if cards suit is space increment space
			if( hand.viewCard(j).getSuit() == 's')
				suits[0] = suits[0] + 1;
			else if( hand.viewCard(j).getSuit() == 'd')
				suits[1] = suits[1] + 1;
			else if( hand.viewCard(j).getSuit() == 'h')
				suits[2] = suits[2] + 1;
			else if( hand.viewCard(j).getSuit() == 'c')
				suits[3] = suits[3] + 1;	
		}
		
	
		
		// royal flush and straight flush
		
		// find if any of hte suits had at least 5  cards (enough for a flush) (only one could have at least 5 bc theres only 7 tops)
		for(j=0; j<4; j++){
			if( suits[j] >=5 ){
				if(j == 0)
					flushSuit = 's';
				if(j == 1)
					flushSuit = 'd';
				if(j == 2)
					flushSuit = 'h';
				if(j == 3)
					flushSuit = 'c';	
			}
		}	
		/// if one of them was greater than 5 then we saved it as flush suit and thus it is not still z
		if(flushSuit != 'z'){ 
		
			// remove all cards not in the flushsuit
			x=0;
			for (x = 0; x<7; x++){
				if(hand.viewCard(x).getSuit() == flushSuit)
					smallerHand.receiveCard(hand.viewCard(x));
			}
				
			
			// royal flush
			if( smallerHand.viewCard(0).getNumber() == 1 && smallerHand.viewCard(1).getNumber() == 13 && smallerHand.viewCard(2).getNumber() == 12
					&& smallerHand.viewCard(3).getNumber() == 11 && smallerHand.viewCard(4).getNumber() == 10){
					rating = 2099;
					return rating;
			}

			// straight flush
			// use a linked list .. run 14 times ,check if u can get 5 trues in a row (true for next card is one less), if true then straight flush 
			// also if false then keep track of the first card u get true for (so just any time false reset the first card poitner
			count = 0;
			cardPtr = 0;
			straightCount = 1;	// count the first card
			initialCardValue = smallerHand.viewCard(0).getNumber();
			while(count < 14){
				if(cardPtr < smallerHand.getAmountOfCards()-1){
					if(smallerHand.viewCard(cardPtr).getNumber() == smallerHand.viewCard(cardPtr+1).getNumber()+1
							|| smallerHand.viewCard(cardPtr).getNumber() == 1 && smallerHand.viewCard(cardPtr+1).getNumber() == 13)
						straightCount++;
					else{
						straightCount = 1;
						initialCardValue = smallerHand.viewCard(cardPtr+1).getNumber();
					}
					cardPtr++;
				}	
				else if(cardPtr == smallerHand.getAmountOfCards()-1){	// for if we are at the last card in the hand
					if(smallerHand.viewCard(cardPtr).getNumber() == 2 && smallerHand.viewCard(0).getNumber() == 1)
						straightCount++;
					else{
						straightCount = 1;
						initialCardValue = smallerHand.viewCard(0).getNumber();
					}	
					cardPtr=0;
				}
				if(straightCount == 5){
					// we have a straight flush
					rating = 1680 + ( 14 * initialCardValue);
					//////////////////////////////////////////////////////////////////////////////////////////
					///////////// if we need the biggest card in teh straight to grade them then just check for that each time straight count is incremented
					///////////////////////////////
					return rating;
				}				
				count++;
			}
			
		}
		
		
		
		
		int[] cards = new int[14];	// will hold hte amount of time each suit is used
		
		cards[0] = 0;	// nothing
		cards[1] = 0;	// ace
		cards[2] = 0;	// two
		cards[3] = 0;	// three 
		cards[4] = 0;	// ..
		cards[5] = 0;
		cards[6] = 0;
		cards[7] = 0;
		cards[8] = 0;
		cards[9] = 0;
		cards[10] = 0;
		cards[11] = 0;
		cards[12] = 0;	// ...
		cards[13] = 0;	// king
		
		for(j = 0; j < 7; j++){
			// if cards suit is space increment space
			if( hand.viewCard(j).getNumber() == 1)
				cards[1] = cards[1] + 1;
			else if( hand.viewCard(j).getNumber() == 2)
				cards[2] = cards[2] + 1;
			else if( hand.viewCard(j).getNumber() == 3)
				cards[3] = cards[3] + 1;	
			else if( hand.viewCard(j).getNumber() == 4)
				cards[4] = cards[4] + 1;
			else if( hand.viewCard(j).getNumber() == 5)
				cards[5] = cards[5] + 1;
			else if( hand.viewCard(j).getNumber() == 6)
				cards[6] = cards[6] + 1;
			else if( hand.viewCard(j).getNumber() == 7)
				cards[7] = cards[7] + 1;
			else if( hand.viewCard(j).getNumber() == 8)
				cards[8] = cards[8] + 1;
			else if( hand.viewCard(j).getNumber() == 9)
				cards[9] = cards[9] + 1;
			else if( hand.viewCard(j).getNumber() == 10)
				cards[10] = cards[10] + 1;
			else if( hand.viewCard(j).getNumber() == 11)
				cards[11] = cards[11] + 1;
			else if( hand.viewCard(j).getNumber() == 12)
				cards[12] = cards[12] + 1;
			else if( hand.viewCard(j).getNumber() == 13)
				cards[13] = cards[13] + 1;		
		}
		
		// check each card value for an of-a-kind
		for(j=1; j<14; j++){
			/// if 4 of a kidn
			if( cards[j] == 4 ){
				fourOfAKind = j;
				if (j == 1)
					j = 14;
				rating = 1470 + ( 14 * j);
		
				return rating;
			}
			// if first 3 of a kind (can be two pairs of 3 of a kind in 7)
			else if( threeOfAKindA == 0 && cards[j] == 3 ){
				threeOfAKindA = j;
			}
			// if first 2 of a kind (can be three pairs in 7 cards)
			else if( twoOfAKindA == 0 && cards[j] == 2 ){
				twoOfAKindA = j;
			}
			// for second 3 of a kinds , so we can find the better of the two
			if( threeOfAKindA > 0 && threeOfAKindA != j && cards[j] == 3){
				threeOfAKindTemp = j;
			}
			// this one cant be else bc there can be two two of a kinds or two and a 3 or three two of a kidns (in 7)
			if ( twoOfAKindA > 0 && twoOfAKindA != j && twoOfAKindB == 0 && cards[j] == 2){
				twoOfAKindB = j;
			}
			if ( twoOfAKindB > 0 && twoOfAKindB != j && cards[j] == 2){
					twoOfAKindTemp = j;
			}
			
		}
	
		// correct for Aces (in terms of rank)
		if(threeOfAKindA == 1)
				threeOfAKindA = 14;
		if(threeOfAKindTemp == 1)
				threeOfAKindTemp = 14;
		if(twoOfAKindA == 1)
				twoOfAKindA = 14;
		if(twoOfAKindB == 1)
				twoOfAKindB = 14;
		if(twoOfAKindTemp == 1)
				twoOfAKindTemp = 14;
		
		
		// now choosing the best 3 of a kind , since u cant use two
		if ( threeOfAKindA != 0 && threeOfAKindTemp != 0 ){
			// put hte biggest one in kindA
			if(threeOfAKindTemp > threeOfAKindA)
				threeOfAKindA = threeOfAKindTemp;
		}	

		// now placing the biggest two of a kind in A, second largest in B, third in Temp (temp wont be used)
		if(twoOfAKindTemp > twoOfAKindA){
			swapKind = twoOfAKindA;
			twoOfAKindA = twoOfAKindTemp;
			twoOfAKindTemp = swapKind;
		}
		if(twoOfAKindTemp > twoOfAKindB){
			swapKind = twoOfAKindB;
			twoOfAKindB = twoOfAKindTemp;
			twoOfAKindTemp = swapKind;
		}	
		// and make A biggest for full houses
		if(twoOfAKindB > twoOfAKindA){
			swapKind = twoOfAKindA;
			twoOfAKindA = twoOfAKindB;
			twoOfAKindB = swapKind;
		}
					
		
		
		// check for full house
		if ( threeOfAKindA > 0 && twoOfAKindA >0 ){
			rating = 1260 + (14 * threeOfAKindA) + twoOfAKindA;
			
			return rating;
		}
		
		
		// flush, we alreayd know if there is a flush from above work but now we just get its highest card inside the flush
		if( flushSuit != 'z' ){
			// now get highest of that suit for comparison with other flushes
			for(int i = 0; i<7; i++){
				// if ace
				if(hand.viewCard(i).getSuit() == flushSuit && hand.viewCard(i).getNumber() == 1){
					rating = 1050 + (14 * 14);
					
					return rating;
				}
				if(hand.viewCard(i).getSuit() == flushSuit && hand.viewCard(i).getNumber() > highCard){
					highCard = hand.viewCard(i).getNumber();
				}
			}
			rating = 1050 + ( 14 * highCard) ;
			
			return rating;
		}	
		
		
		
		
		//straight
		x=0;
		int cx = 0;
		for (x = 0; x<7; x++){
			if(hand.viewCard(x).getSuit() != 'x'){
				if (cx > 0){
					if (hand.viewCard(x).getNumber() != hand.viewCard(x-1).getNumber()){
						smallerHandB.receiveCard(hand.viewCard(x));
					}	
				}
				else if(cx == 0){
					smallerHandB.receiveCard(hand.viewCard(x));
				}
				
			}
			cx++;
		}
		count = 0;
		cardPtr = 0;
		straightCount = 1;	// count the first card
		initialCardValue = smallerHandB.viewCard(0).getNumber();
		while(count < 14){
			if(cardPtr < smallerHandB.getAmountOfCards()-1){
				if(smallerHandB.viewCard(cardPtr).getNumber() == smallerHandB.viewCard(cardPtr+1).getNumber()+1
						|| smallerHandB.viewCard(cardPtr).getNumber() == 1 && smallerHandB.viewCard(cardPtr+1).getNumber() == 13)
					straightCount++;
				else{
					straightCount = 1;
					initialCardValue = smallerHandB.viewCard(cardPtr+1).getNumber();
				}
				cardPtr++;
			}	
			else if(cardPtr == smallerHandB.getAmountOfCards()-1){	// for if we are at the last card in the hand
				if(smallerHandB.viewCard(cardPtr).getNumber() == 2 && smallerHandB.viewCard(0).getNumber() == 1)
					straightCount++;
				else{
					straightCount = 1;
					initialCardValue = smallerHandB.viewCard(0).getNumber();
				}	
				cardPtr=0;
			}
			if(straightCount == 5){
				// we have a straight flush
				rating = 840 + ( 14 * initialCardValue);
				
				return rating;
			}				
			count++;
		}
		
		
		// three of a kind
		if ( threeOfAKindA > 0 ){
			rating = 630 + (14 * threeOfAKindA);
		
			return rating;
		}
		
		// two pair
		if (twoOfAKindA > 0 && twoOfAKindB > 0){
			rating = 420 + (14 * twoOfAKindA) + twoOfAKindB;
			
			return rating;
		}

		// one pair
		if(twoOfAKindA > 0){
			rating = 210 + (14 * twoOfAKindA); 
			
			return rating;
		}
	
		// high card
		for(int i = 0; i<7; i++){
			// if ace
			if(hand.viewCard(i).getNumber() == 1){
				rating = 14 * 14;
			
				return rating;
			}
			if(hand.viewCard(i).getNumber() < highCard){
				highCard = hand.viewCard(i).getNumber();
			}
		}
	
		rating = 14 * highCard;
		return rating;
	}
}